from django.shortcuts import render, redirect
from django.views.generic import CreateView, ListView, DeleteView, UpdateView, DetailView
from django.views.generic.base import TemplateView
from django.contrib.auth.models import User
#from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import LoginRequiredMixin
from django.urls import reverse_lazy
from django.http import HttpResponse, JsonResponse
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.db.models import F ##一个数据库中的两个字段比较需要用到
import json

from customer.models import CustomerModel as Customer
from product.models import ProductModel as Product
from product.views import GetCategroyProductTree
from .models import OrderModel as Order, OrderContentModel as OrderContent
from .forms import OrderAddForm

# Create your views here.
##BEGIN: Add by SRJ-SGL 
#客户列表
class OrderListCondition(): 
    def expired():
        q = {}
        q['balance__lt'] = 0
        return q

    def today_expired(): 
        q = {}
        q['balance__gte'] = 0
        q['balance__lt'] = F('price')
        return q

    def In3days_expired(): 
        q = {}
        q['balance__gte'] = 0
        q['balance__lt'] = F('price') * 3
        return q

    def In7days_expired(): 
        q = {}
        q['balance__gte'] = 0
        q['balance__lt'] = F('price') * 7
        return q
        
class OrderVerifyKeyExist(LoginRequiredMixin, ListView): 

    def post(self, request, *args, **kwargs):
        orders = Order.objects.filter(orderid=request.POST.get('name'))

        resultdict = {}

        if (orders.count() > 0):
            resultdict['code'] = 1
            #resultdict['msg'] = orders.first().orderid + ' 已存在!'
            return JsonResponse(resultdict, safe=False) 
        else:
            resultdict['code'] = 0
            return JsonResponse(resultdict, safe=False) 

class OrderListCaseExpireView(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('user_login') 
    template_name = "order/order-list-case.html"

    def get(self, request, *args, **kwargs):
        return render(request, self.template_name, {"cid": kwargs.get('cid')})

    def post(self, request, *args, **kwargs):
        ## 过滤条件参数
        ## 判断是搜索的数据还是直接显示的数据
        page = request.POST.get('page')
        rows = request.POST.get('limit')
        cid = kwargs.get('cid')

        if cid == 1:  ##已逾期
            q = OrderListCondition.expired()
        elif cid == 2:  ##今天到期
            q = OrderListCondition.today_expired()
        elif cid == 3:   ##3天内将要逾期
            q = OrderListCondition.In3days_expired()
        elif cid == 4:  ##7天内将要逾期
            q = OrderListCondition.In7days_expired()

        orders = Order.objects.filter(**q)
        total = orders.count()

        start = (int(page) - 1) * int(rows)
        end = (int(page) - 1) * int(rows) + int(rows)

        total = orders.count()
        orders = orders[start:end]

        dict = []
        resultdict = {}

        for order in orders:
            dic = {}
            dic['id'] = order.id
            dic['orderid'] = order.orderid
            dic['customer'] = order.customer.name
            dic['deposit'] = order.deposit
            dic['price'] = order.price
            dic['effectdays'] = order.effectdays
            dic['balance'] = order.balance
            dic['comment'] = order.comment
            dic['orderdate'] = order.orderdate.strftime("%Y-%m-%d")
            dict.append(dic)

        resultdict['code'] = 0
        resultdict['msg'] = ""
        resultdict['count'] = total 
        resultdict['data'] = dict

        return JsonResponse(resultdict, safe=False) 

class OrderListPageView(LoginRequiredMixin, ListView):
    ## login_url = "/account/login/"  和下边一行的功能是一样的,一个是硬编码,一个是灵活实现
    login_url = reverse_lazy('user_login') 
    template_name = "order/order-list.html"
    search_fields = ('orderid', 'customer__name', 'orderdate')

    def get(self, request):
        return render(request, self.template_name)

    def post(self, request, *args, **kwargs):
        ## 过滤条件参数
        ## 判断是搜索的数据还是直接显示的数据
        q = {}
        page = request.POST.get('page')
        rows = request.POST.get('limit')

        filter_orderid = request.POST.get('filter_orderid')         
        filter_customer = request.POST.get('filter_customer')         
        filter_orderdate = request.POST.get('filter_orderdate')
        
        if filter_orderid:
            q['orderid__icontains'] = filter_orderid
        if filter_customer: ##外键不能直接过滤,需要指定过滤外键的哪个字段
            q['customer__name__icontains'] = filter_customer
        if filter_orderdate:
            q['orderdate__icontains'] = filter_orderdate

        orders = Order.objects.filter(**q)

        start = (int(page) - 1) * int(rows)
        end = (int(page) - 1) * int(rows) + int(rows)

        total = orders.count()
        orders = orders[start:end]

        dict = []
        resultdict = {}

        for order in orders:
            order.update_data_per_days()
            dic = {}
            dic['id'] = order.id
            dic['orderid'] = order.orderid
            dic['customer'] = order.customer.name
            dic['deposit'] = order.deposit
            dic['price'] = order.price
            dic['effectdays'] = order.effectdays
            dic['balance'] = order.balance
            dic['comment'] = order.comment
            dic['orderdate'] = order.orderdate.strftime("%Y-%m-%d")
            dict.append(dic)

        resultdict['code'] = 0
        resultdict['msg'] = ""
        resultdict['count'] = total 
        resultdict['data'] = dict

        return JsonResponse(resultdict, safe=False) 

class OrderAddPageView(LoginRequiredMixin, CreateView):
    login_url = "/account/login/"
    template_name = "order/order-add.html"
    ## fileds为页面上的表单要显示的项
    ##fields = ['orderid', 'customer', 'contact', 'phone', 'deposit',
    ##          'price', 'comment']

    ##Note1 此处只能使用这个,因为要返回customers做为下拉列表的内容 
    def get(self, request):
        customers = Customer.objects.all()
        productTreeData = GetCategroyProductTree.getZtreeData(None)
        return render(request, "order/order-add.html", {"customers":customers, "productTreeData":productTreeData})
    
    ##Note2 当继承的是CreateView时使用这个,功能与Note1是一样的,只是两种不同的实现方式
    ##queryset = Order.objects.all()

    def post(self, request, *args, **kwargs):
        orderFormObj = OrderAddForm(request.POST)
        resultdict = {}

        if orderFormObj.is_valid():
            ##保存订单信息
            form_cd = orderFormObj.cleaned_data 

            new_order = orderFormObj.save(commit=False) ## form.save(commit=False)返回的是一个Model对象
            new_order.effectdays = new_order.get_effect_days()
            new_order.balance = new_order.get_balance()
            new_order.save(form_cd)

            ##保存订单内容信息
            for key in request.POST:
                if ("productname_" in key):
                    productId = key[len("productname_"):]
                    productCount = request.POST.get(key) 
                    productCategoryId = Product.objects.get(id=productId).getCategoryId()
                    ##方式一
                    ##OrderContent.objects.create(new_order.id ,productCategoryId, productId, productCount)
                    ##方式二
                    orderContent = OrderContent()
                    orderContent.order_id = new_order.id 
                    orderContent.productId = productId
                    orderContent.productCategoryId = productCategoryId
                    orderContent.productCount = productCount
                    orderContent.save()

            resultdict['code'] = 0
            resultdict['msg'] = ""
            return JsonResponse(resultdict, safe=False) 
        else:
            print ("===================xxxx",orderFormObj.errors)

        return self.render_to_response({"form":orderFormObj})

class OrderDelPageView(LoginRequiredMixin, DeleteView):
    login_url = "/account/login/"
    success_url = reverse_lazy('order:show_orderList')

    model = Order

    def delete(self, request, *args, **kwargs):
        ##for k, v in kwargs.items():
        ##    print ('%s，%s；' , (k, v))
        super(OrderDelPageView, self).delete(request, *args, **kwargs)
        return JsonResponse({'code':0, 'msg':''}) 

##class OrderDetailPageView(LoginRequiredMixin, DeleteView):
##    template_name = "order/order-update.html"
##    context_object_name = "order"
##
##    model = Order
##
##    ##如果不要下边的这个函数,是不会把信息返回到表单的
##    ##def get_object(self, queryset=None):
##    ##    obj = super(OrderDetailPageView, self).get_object()
##    ##    return obj
##
##    ##下边注释的两个函数其实放开效果是一样的,只不过是记录一下怎么取url中的参数的方法
##    ##def get_object(self,queryset=None):
##    ##    obj_id = int(self.kwargs.get(self.pk_url_kwarg, None))
##    ##    obj = self.model.objects.get(id = obj_id)
##    ##    return obj 
##    
##    def get_context_data(self, **kwargs):
##        context = super(OrderDetailPageView, self).get_context_data(**kwargs)
##        return context
##

class OrderUpdatePageView(LoginRequiredMixin, UpdateView):
    login_url = "/account/login/"
    success_url = reverse_lazy('order:show_orderList')

    template_name = "order/order-update.html"
    template_name_suffix = '_update_form'
    fields = ['deposit', 'price', 'comment']
    context_object_name = "order"

    model = Order

    ##def get_form_kwargs(self):
    ##    kwargs = super(OrderUpdatePageView,self).get_form_kwargs()
    ##    print ("==============kwargs id", self.kwargs['pk'])
    ##    return kwargs

    def get_object(self, queryset=None):
        obj = super(OrderUpdatePageView, self).get_object()
        return obj

    def get_context_data(self, **kwargs):
        context = super(OrderUpdatePageView, self).get_context_data(**kwargs)
        ##order_id = context['object'].id ##记录一下通过context获取对象的方法
        productTreeData = GetCategroyProductTree.getZtreeData(context['object'].id)
        context['productTreeData'] = productTreeData
        return context

    def post(self, request, *args, **kwargs):
        orderFormObj = OrderAddForm(request.POST)
        resultdict = {}

        if orderFormObj.is_valid():
            ## 创建事务保存点
            with transaction.atomic():
                save_id = transaction.savepoint()

                try:
                    form_cd = orderFormObj.cleaned_data 

                    ##order = Order.objects.get(id=self.kwargs['pk'])  ##和下边的功能一样,记录两种方式
                    order = self.get_object() 
                    order.deposit = form_cd['deposit']  
                    order.price = form_cd['price']
                    order.orderdate = form_cd['orderdate']
                    order.comment = form_cd['comment']
                    order.effectdays = order.get_effect_days()
                    order.balance = order.get_balance()
                    order.save()

                    ##更新订单内容采用增量添加,存量更新
                    for key in request.POST:
                        if ("productname_" in key):
                            productId = key[len("productname_"):]
                            productCount = request.POST.get(key) 
                            productCategoryId = Product.objects.get(id=productId).getCategoryId()
                            try:
                                content = OrderContent.objects.get(productId=productId, order_id=order.id)
                                content.productCount = productCount
                                if (int(productCount) == 0):
                                    content.delete()
                                else:
                                    content.save()
                            except Exception as e:
                                ##新保存的订单内容
                                orderContent = OrderContent()
                                orderContent.order_id = order.id 
                                orderContent.productId = productId
                                orderContent.productCategoryId = productCategoryId
                                orderContent.productCount = productCount
                                orderContent.save()
                except Exception as e:
                    transaction.savepoint_rollback(save_id)

                transaction.savepoint_commit(save_id)
                resultdict['code'] = 0
                resultdict['msg'] = ""
                return JsonResponse(resultdict, safe=False) 
        else:
            print ("===================xxxx",orderFormObj.errors)

        return self.render_to_response({"form":orderFormObj})

class OrderDetailPageView(LoginRequiredMixin, ListView):
    ## login_url = "/account/login/"  和下边一行的功能是一样的,一个是硬编码,一个是灵活实现
    login_url = reverse_lazy('user_login') 
    template_name = "order/order-detail.html"

    def get(self, request, *args, **kwargs):
        return render(request, self.template_name, {"order_id": kwargs.get('pk')})

    def post(self, request, *args, **kwargs):
        ## 过滤条件参数
        ## 判断是搜索的数据还是直接显示的数据
        page = request.POST.get('page')
        rows = request.POST.get('limit')
        orderid = kwargs.get('pk')

        contents = OrderContent.objects.filter(order_id=orderid)

        start = (int(page) - 1) * int(rows)
        end = (int(page) - 1) * int(rows) + int(rows)

        total = contents.count()
        contents = contents[start:end]

        dict = []
        resultdict = {}

        for obj in contents:
            dic = {}
            product = Product.objects.get(id=obj.productId)
            dic['name'] = product.name
            dic['spec'] = product.spec 
            dic['count'] = obj.productCount
            dict.append(dic)

        resultdict['code'] = 0
        resultdict['msg'] = ""
        resultdict['count'] = total 
        resultdict['data'] = dict

        return JsonResponse(resultdict, safe=False) 

####END: Add by SRJ-SGL 
